Running github action on your home server
Intro
For anyone deeply involved in hobby projects or extensive experiments, rapid iteration is not just a luxury—it’s a necessity. This is where Continuous Integration/Continuous Delivery (CI/CD) pipelines become indispensable. They allow you to automate the testing and deployment of your code, ensuring quick feedback and preventing regressions. Among the many CI/CD tools available, GitHub Actions stands out for its seamless integration within the GitHub ecosystem.
While GitHub Actions offers a generous free tier, larger projects or more frequent builds can quickly hit those limits. This is where running a self-hosted runner on your own hardware, like a home server, becomes an incredibly cost-effective and powerful alternative. It puts the build process directly under your control, leveraging your existing hardware and bypassing any potential cloud-based limitations.
Preparing Your Home Server
The first step is to get your server ready. In my setup, I utilize both a HP EliteDesk and a Raspberry Pi, both running 24/7. These machines are perfect for continuous operations, providing a reliable foundation for CI/CD.
A significant portion of my projects involves Android development, which necessitates the Android SDK. This introduces a crucial compatibility consideration:
- Operating System and Architecture: While a Raspberry Pi (ARM architecture) is energy-efficient, I discovered that the Android SDK command-line tools do not officially support ARM. This means that if your project requires Android SDK builds, a standard x86-64 machine like the HP EliteDesk is necessary. For projects not requiring Android SDK (e.g., web development, Python scripts), a Raspberry Pi could still be a viable and power-efficient option.
Installation and Configuration
For robust and reproducible server setups, I highly recommend using a configuration management tool like Ansible. Ansible allows you to define your server’s desired state in code, making installations consistent and easy to replicate across multiple machines or after a system rebuild. You can find numerous Ansible roles and playbooks specifically designed for setting up build environments, including those for Android development.
My typical setup process with Ansible involves:
- OS Preparation: Ensuring the base operating system (e.g., Ubuntu, Debian) is up-to-date.
- Java Development Kit (JDK): Installing the appropriate JDK version required by the Android SDK.
- Android SDK: Downloading and configuring the Android SDK command-line tools, accepting licenses, and setting up environment variables like
ANDROID_HOME
. - Other Dependencies: Installing any other tools or libraries specific to your project’s build process (e.g., Node.js, Python, specific compilers).
Setting Up the GitHub Actions Runner
Once your home server is adequately prepared with all the necessary dependencies, the next step is to register it as a self-hosted runner with GitHub.
-
Navigate to GitHub Runner Settings:
- Go to your repository on GitHub.
- Click on
Settings
(usually in the top right of the repo page). - In the left sidebar, click on
Actions
>Runners
. - Click on
New self-hosted runner
.
-
Choose Your Operating System and Architecture:
- GitHub will provide specific instructions tailored to your server’s OS (e.g., Linux, Windows, macOS) and architecture (e.g., x64).
-
Download and Configure the Runner Application:
- You’ll see a series of commands to:
- Create a directory for the runner.
- Download the runner application package (a compressed file).
- Extract the package.
- Run the configuration script (
./config.sh
). This script will prompt you for the runner’s URL (provided by GitHub) and a token. It also allows you to assign labels to your runner, which is useful for targeting specific workflows to specific machines (e.g.,android-build-server
,x64
).
Here’s a snippet of what these commands typically look like for a Linux x64 system:
# Create a folder mkdir actions-runner && cd actions-runner # Download the latest runner package curl -o actions-runner-linux-x64-2.316.0.tar.gz -L [https://github.com/actions/runner/releases/download/v2.316.0/actions-runner-linux-x64-2.316.0.tar.gz](https://github.com/actions/runner/releases/download/v2.316.0/actions-runner-linux-x64-2.316.0.tar.gz) # Extract the installer tar xzf ./actions-runner-linux-x64-2.316.0.tar.gz # Configure the runner (replace URL and token with values from GitHub) ./config.sh --url [https://github.com/YOUR_USERNAME/YOUR_REPOSITORY](https://github.com/YOUR_USERNAME/YOUR_REPOSITORY) --token A_GENERATED_TOKEN # Optional: Run the runner directly (for testing) # ./run.sh
- You’ll see a series of commands to:
-
Run the Runner Service:
- After successful configuration, GitHub will provide a command to run the runner. For persistent operation, you’ll typically set it up as a background service. A common command for this on Linux is
sudo ./svc.sh install
followed bysudo ./svc.sh start
to register and start it as a system service. This ensures the runner automatically restarts if your server reboots.
# Install the service sudo ./svc.sh install # Start the service sudo ./svc.sh start
- After successful configuration, GitHub will provide a command to run the runner. For persistent operation, you’ll typically set it up as a background service. A common command for this on Linux is
Creating Your GitHub Actions Workflow
With your self-hosted runner online and waiting for jobs, you can now modify or create your GitHub Actions workflow file.
-
Locate Your Workflow Directory:
- In your GitHub repository, navigate to the
.github/workflows/
directory. If it doesn’t exist, create it.
- In your GitHub repository, navigate to the
-
Create or Edit a Workflow File:
- Create a new YAML file (e.g.,
build-android.yml
) or edit an existing one.
- Create a new YAML file (e.g.,
-
Specify
runs-on: self-hosted
:- The crucial change is within your job definition. Instead of
runs-on: ubuntu-latest
orruns-on: windows-latest
, you’ll specifyruns-on: self-hosted
. - If you assigned specific labels during runner configuration, you can use those to target the runner more precisely. For example, if you labeled your Android build server
android-x64
, your workflow job would look like this:
jobs: build: runs-on: [self-hosted, android-x64] # Targets a self-hosted runner with the 'android-x64' label steps: - uses: actions/checkout@v4 - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' - name: Build Android project run: ./gradlew assembleDebug # ... other steps
This setup routes the build job directly to your home server, leveraging its resources and your pre-installed Android SDK.
- The crucial change is within your job definition. Instead of
Conclusion
Running GitHub Actions on your home server is a powerful way to extend your CI/CD capabilities beyond the limitations of cloud-based free tiers. It provides greater control, can save costs in the long run, and allows you to utilize specialized hardware like a powerful EliteDesk for demanding tasks like Android compilation. With a bit of initial setup, you’ll have a robust and flexible CI/CD pipeline right in your home.
Have you considered other ways to optimize your CI/CD workflow at home?
~Fajar Ulin Nuha